package com.htdata.iiot.api.tsdb.controller;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.htdata.iiot.api.tsdb.pojo.DeviceStatusData;
import com.htdata.iiot.api.tsdb.utils.QueryDstatus;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping(value = "/dstatus")
public class DeviceStatusDataServiceImpl {
    private QueryDstatus queryDstatus = new QueryDstatus();
    private Logger logger = LogManager.getLogger(DeviceStatusDataServiceImpl.class);

    @RequestMapping(value = "/rel", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
    public String getRelDataRest(@RequestParam("did") String dids,
                                 @RequestParam(name = "size", defaultValue = "1", required = false) int size) {

        Map<String, DeviceStatusData[]> relData = new HashMap<String, DeviceStatusData[]>();
        int code = 0;
        String message = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
            String startTime = sdf.format(new Date());
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String endTime = sdf2.format(new Date());
            relData = getHistoryData(dids,startTime,endTime,"1d-last-none");
        } catch (Exception e) {
            logger.error(e);
            e.printStackTrace();
            message = e.getMessage();
            code = 1;
        }

        return buildResult(code, relData, message);
    }

    private String buildResult(int code, final Map<String, DeviceStatusData[]> result, String message) {
        ObjectMapper mapper = new ObjectMapper();
        StringWriter writer = new StringWriter();
        try {
            JsonGenerator jsonGenerator = mapper.getFactory().createGenerator(writer);
            jsonGenerator.writeStartObject();
            jsonGenerator.writeNumberField("code", code);
            if (message != null) {
                jsonGenerator.writeStringField("message", message);
            }
            if(result!=null) {
                jsonGenerator.writeObjectFieldStart("data");
                for (Map.Entry<String, DeviceStatusData[]> entry : result.entrySet()) {
                    String did = entry.getKey();
                    jsonGenerator.writeArrayFieldStart(did);
                    DeviceStatusData[] datapoints = entry.getValue();
                    for (DeviceStatusData dp : datapoints) {
                        jsonGenerator.writeObject(dp);
                    }
                    jsonGenerator.writeEndArray();
                }
            }
            jsonGenerator.writeEndObject();
            jsonGenerator.flush();
            jsonGenerator.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return writer.toString();
    }

    @RequestMapping(value = "/getHistoryData", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
    public String getHistoryDataRest(@RequestParam("did") String dids,@RequestParam("start") String startTime,
                                                          @RequestParam("end") String endTime,@RequestParam(value = "ds",defaultValue = "1s-avg-none",required = false) String downsample) throws Exception {
        logger.info("search devicestatusdata ,its params are dids: " + dids +" start: "+startTime+" end: "+endTime+" ds: "+downsample);
        Map<String,DeviceStatusData[]> historyData = new HashMap<String,DeviceStatusData[]>();
        int code = 0;
        String message = null;
        try {
            historyData = getHistoryData(dids,startTime,endTime,downsample);
        }catch (Exception e){
            logger.error(e);
            e.printStackTrace();
            message = e.getMessage();
            code = 1;
        }
        return buildResult(code,historyData,message);
    }


    public Map<String, DeviceStatusData[]> getHistoryData(String dids, String startTime, String endTime,String downsample) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, DeviceStatusData[]> result = new HashMap<String, DeviceStatusData[]>();
        if (!"".equals(dids) && dids != null) {
            String[] didArr = dids.split(",");
            if (didArr != null && !"".equals(startTime) && startTime != null && !"".equals(endTime)
                    && endTime != null) {
                for (int i = 0; i < didArr.length; i++) {
                    String did = didArr[i];
                    Date startDate = sdf.parse(startTime);
                    Date endDate = sdf.parse(endTime);

                    DeviceStatusData[] dPoint = new DeviceStatusData[0];
                    try {
                        DeviceStatusData[] deviceStatusData = queryDstatus.getTSData(did, startDate, endDate, downsample);
                        logger.info(did + " searched result Size: " + deviceStatusData.length + " in time :" + startTime
                                + " ~ " + endTime + " ds:" + downsample);
                        dPoint = deviceStatusData;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    result.put(did, dPoint);
                }
            }
        }
        return result;
    }
}
